package com.qike.duola.service.impl;

import com.alibaba.fastjson.JSON;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.*;
import com.qike.duola.mapper.*;
import com.qike.duola.service.*;
import com.qike.duola.utils.DistanceUtil;
import com.qike.duola.utils.TimeTool;
import com.qike.duola.vo.*;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @Author: Eric.zhou
 * @Date: 2020/9/2 15:10
 */
@Service
public class DuolaTransOrderServiceImpl implements DuolaTransOrderService {

    private static final Logger logger = LoggerFactory.getLogger(DuolaTransOrderServiceImpl.class);

    @Autowired
    private DuolaCarMapper duolaCarMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private DuolaTransOrderMapper transOrderMapper;
    @Autowired
    private DuolaProjectMapper duolaProjectMapper;
    @Autowired
    private DuolaLineMapper duolaLineMapper;
    @Autowired
    private DuolaLineTransMapper duolaLineTransMapper;
    @Autowired
    private DuolaCarRemainMapper duolaCarRemainMapper;
    @Autowired
    private DuolaPlanMapper duolaPlanMapper;
    @Autowired
    private DuolaGoodsMapper duolaGoodsMapper;
    @Autowired
    private DuolaCustomerMapper duolaCustomerMapper;
    @Autowired
    private SocketService socketService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private DuolaLineService duolaLineService;
    @Autowired
    private NoticeService noticeService;


    /**
     * 发货
     *
     * @param sendGoodsDto
     */
    @Override
    @Transactional
    public void sendGoods(SendGoodsDto sendGoodsDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"发货"+ JSON.toJSON(sendGoodsDto));
        Integer planId = sendGoodsDto.getPlanId();
        DuolaPlan duolaPlan = duolaPlanMapper.selectByPrimaryKey(planId);
        if (duolaPlan == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(sendGoodsDto.getCarId());
        car.setTransStatus(CarTransStatusEnums.BUMP_CAR.getEcode());
        duolaCarMapper.updateByPrimaryKeySelective(car);
        if (CarTransStatusEnums.BUMP_CAR.getEcode().equals(car.getTransStatus())){
            throw new Exception(ErrorEnums.CAN_NOT_LOAD.getEmsg());
        }
        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(car.getDriverId());
        DuolaTransOrder duolaTransOrder = new DuolaTransOrder();
        duolaTransOrder.setAddTime(LocalDateTime.now());
        duolaTransOrder.setAddUid(userId);
        duolaTransOrder.setLineId(sendGoodsDto.getLineId());
        duolaTransOrder.setCarId(sendGoodsDto.getCarId());
        duolaTransOrder.setGoodsId(sendGoodsDto.getGoodsId());
        duolaTransOrder.setUpdateTime(LocalDateTime.now());
        duolaTransOrder.setStatus(StatusEnums.NO.getEcode());
        duolaTransOrder.setSendType(sendGoodsDto.getSendType());
        duolaTransOrder.setPlanId(sendGoodsDto.getPlanId());
        duolaTransOrder.setProjectId(duolaPlan.getProjectId());
        DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(duolaPlan.getProjectId());
        duolaTransOrder.setDistance( duolaProject.getDistance());
        duolaTransOrder.setOrderStatus(TransOrderStatusEnums.WAIT_LOAD.getEcode());

        duolaTransOrder.setCarNo(car.getCarNo());
        transOrderMapper.insertSelective(duolaTransOrder);
        //生产线进行排队
        Integer sort = 1;
        DuolaLineTransExample example = new DuolaLineTransExample();
        example.createCriteria().andLineIdEqualTo(sendGoodsDto.getLineId()).andStatusEqualTo(StatusEnums.NO.getEcode());
        example.setOrderByClause("sort desc");
        List<DuolaLineTrans> duolaLineTrans = duolaLineTransMapper.selectByExample(example);
        if (duolaLineTrans.size() > 0) {
            sort = duolaLineTrans.get(0).getSort() + 1;
        }
        DuolaLineTrans newTrans = new DuolaLineTrans();
        newTrans.setCarId(sendGoodsDto.getCarId());
        newTrans.setStatus(StatusEnums.NO.getEcode());
        newTrans.setTransId(duolaTransOrder.getId());
        newTrans.setSort(sort);
        DuolaLineTransExample lastExample = new DuolaLineTransExample();
        lastExample.createCriteria().andLineIdEqualTo(sendGoodsDto.getLineId()).andStatusEqualTo(StatusEnums.NO.getEcode()).andSortEqualTo(sort-1);
        List<DuolaLineTrans> lastCarList = duolaLineTransMapper.selectByExample(lastExample);
        if (lastCarList!=null&&lastCarList.size()>0){
            newTrans.setLastCarId(lastCarList.get(0).getCarId());
        }else {
            newTrans.setLastCarId(0);
        }
        newTrans.setLineId(sendGoodsDto.getLineId());
        duolaLineTransMapper.insertSelective(newTrans);
        //查询前一辆车
        DuolaCar lastCar = null;
        if (duolaLineTrans.size()>0){
            DuolaLineTrans lastTrans = duolaLineTrans.get(0);
            if (lastTrans!=null){
                Integer carId = lastTrans.getCarId();
                lastCar = duolaCarMapper.selectByPrimaryKey(carId);

            }
        }
        //发送生产线长连接
        socketService.sendNewTransLineSocket();
        //车变为运输中的状态
        DuolaCar duolaCar = new DuolaCar();
        duolaCar.setId(car.getId());
        duolaCar.setTransStatus(CarTransStatusEnums.BUMP_CAR.getEcode());
        duolaCarMapper.updateByPrimaryKeySelective(duolaCar);
        socketService.sendNewTransOrderListSocket();
        //生产计划变为生产中
        duolaPlan.setOrderStatus(PlanOrderStatusEnums.DRIVING.getEcode());
        duolaPlanMapper.updateByPrimaryKeySelective(duolaPlan);
        //todo 装料通知
        try {
            if (lastCar!=null){
                noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),car.getCarNo(),sendGoodsDto.getLineId().toString(),lastCar.getCarNo());
            }else {
                noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),car.getCarNo(),sendGoodsDto.getLineId().toString(),"空");
            }
        } catch (Exception e) {
        }
    }


    /**
     * 运输单列表
     *
     * @param planId
     * @param carNo
     * @return
     */
    @Override
    public List<TransListVo> TransList(Integer planId, String carNo) {
//        if (planId==0){
//            planId=null;
//        }
        List<TransListVo> listVos = new ArrayList<>();

        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"运输单列表"+ JSON.toJSON(planId));
        DuolaTransOrderExample example = new DuolaTransOrderExample();
        DuolaTransOrderExample.Criteria criteria = example.createCriteria();
        if (planId != null&&planId!=0) {
            criteria.andPlanIdEqualTo(planId);
        }
        if (!StringUtils.isEmpty(carNo)&&!"null".equals(carNo)) {
            criteria.andCarNoLike(carNo);
        }
        //获取所有车辆余料
        HashMap<Integer, Double> carRemainsMap = new HashMap<>();
        List<DuolaCarRemain> duolaCarRemains = duolaCarRemainMapper.selectByExample(new DuolaCarRemainExample());
        for (DuolaCarRemain duolaCarRemain : duolaCarRemains) {
            carRemainsMap.put(duolaCarRemain.getCarId(), duolaCarRemain.getRemain());
        }
        //查询计划下车辆状态
        if (planId != null) {
            //获取所有车辆的信息
            HashMap<Integer, DuolaCar> carHashMap = new HashMap<>();
            DuolaCarExample carExample = new DuolaCarExample();
//            carExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode());
            List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(carExample);
            for (DuolaCar duolaCar : duolaCars) {
                carHashMap.put(duolaCar.getId(), duolaCar);
            }
            example.setOrderByClause("update_time desc");
            List<DuolaTransOrder> duolaTransOrders = transOrderMapper.selectByExample(example);
            for (DuolaTransOrder duolaTransOrder : duolaTransOrders) {
                TransListVo vo = new TransListVo();
                vo.setTime(TimeTool.LocalDateTimeFormat(duolaTransOrder.getUpdateTime()));
                vo.setCarId(duolaTransOrder.getCarId());
                vo.setCarNo(duolaTransOrder.getCarNo());
                vo.setId(duolaTransOrder.getId());
                vo.setSendVolume(duolaTransOrder.getTotalVolume());
                vo.setSignVolume(duolaTransOrder.getSignVolume());
                vo.setRemain(carRemainsMap.get(duolaTransOrder.getCarId()) == null ? new Double(0) : carRemainsMap.get(duolaTransOrder.getCarId()));
                vo.setCarType(carHashMap.get(duolaTransOrder.getCarId()).getCapacity());
                vo.setStatus(duolaTransOrder.getOrderStatus());
                vo.setStatusStr(TransOrderStatusEnums.statOf(duolaTransOrder.getOrderStatus()).getEmsg());
                listVos.add(vo);
            }
        } else {
            //查询所有最新的运输单
            Map<Integer, DuolaTransOrder> transCarMap = new HashMap<>();
            List<DuolaTransOrder> duolaTransOrders = transOrderMapper.selectByGroup();
            for (DuolaTransOrder duolaTransOrder : duolaTransOrders) {
                transCarMap.put(duolaTransOrder.getCarId(), duolaTransOrder);
            }
            //查询所有车辆的状态
            DuolaCarExample carExample = new DuolaCarExample();
            DuolaCarExample.Criteria criteria1 = carExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode()).andCarStatusEqualTo(CarStatusEnums.YES.getEcode());
            if (!StringUtils.isEmpty(carNo)&&!"null".equals(carNo)) {
                criteria1.andCarNoLike(carNo);
            }
            List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(carExample);
            for (DuolaCar duolaCar : duolaCars) {
                TransListVo vo = new TransListVo();
                if (transCarMap.get(duolaCar.getId())!=null){
                    vo.setId(transCarMap.get(duolaCar.getId()).getId());

                }
                vo.setCarId(duolaCar.getId());
                vo.setCarNo(duolaCar.getCarNo());
                vo.setType(duolaCar.getCarType());
                if (duolaCar.getTransStatus() != null && duolaCar.getTransStatus().equals(CarTransStatusEnums.MIX_CAR.getEcode())) {
//                    vo.setSendVolume(duolaTransOrder.getTotalVolume());
//                    vo.setSignVolume(duolaTransOrder.getSignVolume());
                    vo.setRemain(carRemainsMap.get(duolaCar.getId()) == null ? new Double(0) : carRemainsMap.get(duolaCar.getId()));
                    vo.setCarType(duolaCar.getCapacity());
                    vo.setStatus(0);
                    vo.setStatusStr(CarTransStatusEnums.MIX_CAR.getEmsg());
                } else {
                    if (transCarMap.get(duolaCar.getId()) != null) {
                        vo.setSendVolume(transCarMap.get(duolaCar.getId()).getTotalVolume());
                        vo.setSignVolume(transCarMap.get(duolaCar.getId()).getSignVolume());
                        vo.setStatus(transCarMap.get(duolaCar.getId()).getOrderStatus());
                        vo.setStatusStr(TransOrderStatusEnums.statOf(transCarMap.get(duolaCar.getId()).getOrderStatus()).getEmsg());
                        vo.setRemain(carRemainsMap.get(duolaCar.getId()) == null ? new Double(0) : carRemainsMap.get(duolaCar.getId()));
                        vo.setCarType(duolaCar.getCapacity());
                    }
                }
                listVos.add(vo);

            }
        }

        return listVos;
    }

    /**
     * 装料
     *
     * @param loadGoodsDto
     */
    @Override
    @Transactional
    public void loadGoods(LoadGoodsDto loadGoodsDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"装料"+ JSON.toJSON(loadGoodsDto));
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(loadGoodsDto.getCarId());
//        if (car.getTransStatus().equals(CarTransStatusEnums.MIX_CAR.getEcode())){
        if (CarTransStatusEnums.MIX_CAR.getEcode().equals((car.getTransStatus()))){
            throw new Exception(ErrorEnums.CAN_NOT_LOAD.getEmsg());
        }
        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(car.getDriverId());
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(loadGoodsDto.getTransId());
        if (duolaTransOrder == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        duolaTransOrder.setLoadTime(LocalDateTime.now());
        duolaTransOrder.setFormulaId(loadGoodsDto.getFormulaId());
        //如果使用余料 总数= 实际装料+余料
        if (loadGoodsDto.getUseRemain()) {
            DuolaCarRemain duolaCarRemain = duolaCarRemainMapper.selectByPrimaryKey(loadGoodsDto.getCarId());
            duolaTransOrder.setTotalVolume(loadGoodsDto.getTotalVolume() + duolaCarRemain.getRemain());
        } else {
            duolaTransOrder.setTotalVolume(loadGoodsDto.getTotalVolume());
        }
        duolaTransOrder.setOrderStatus(TransOrderStatusEnums.LOAD_FINISH.getEcode());
        duolaTransOrder.setUpdateTime(LocalDateTime.now());
        transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
        //移除队列
//        DuolaLineTrans duolaLineTrans = duolaLineTransMapper.selectByPrimaryKey(loadGoodsDto.getTransId());
//        duolaLineTrans.setStatus(StatusEnums.YES.getEcode());
        DuolaLineTrans duolaLineTrans = new DuolaLineTrans();
        duolaLineTrans.setId(loadGoodsDto.getId());
        duolaLineTrans.setTransId(loadGoodsDto.getTransId());
        duolaLineTrans.setStatus(StatusEnums.YES.getEcode());
        duolaLineTransMapper.updateByPrimaryKeySelective(duolaLineTrans);
        //车辆变为非空闲
        car.setTransStatus(CarTransStatusEnums.BUMP_CAR.getEcode());
        duolaCarMapper.updateByPrimaryKeySelective(car);
        //长连接
        socketService.sendNewTransLineSocket();
        socketService.sendNewTransOrderListSocket();
        //获取工程
        Integer projectId = duolaTransOrder.getProjectId();
        DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(projectId);
        //todo 发货通知
        try {
            noticeService.sendGoods(sysUserWithBLOBs.getMobilePhone(),car.getCarNo(),duolaProject.getProjectName(),duolaProject.getDistance().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 装料跳转
     *
     * @param transId
     * @return
     */
    @Override
    public LoadGoodsJumpVo loadGoodsJump(Integer transId) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"装料跳转"+ JSON.toJSON(transId));
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(transId);
        if (duolaTransOrder == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        LoadGoodsJumpVo vo = new LoadGoodsJumpVo();
        vo.setCarNo(duolaTransOrder.getCarNo());
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(duolaTransOrder.getCarId());
        if (car.getCapacity()!=null){
            vo.setCarType(car.getCapacity().toString());
        }
        DuolaCarRemain duolaCarRemain = duolaCarRemainMapper.selectByPrimaryKey(car.getId());
        if (duolaCarRemain != null) {
            vo.setRemain(duolaCarRemain.getRemain());
        }
        DuolaPlan duolaPlan = duolaPlanMapper.selectByPrimaryKey(duolaTransOrder.getPlanId());
        DuolaGoods duolaGoods = duolaGoodsMapper.selectByPrimaryKey(duolaPlan.getGoodsId());
        vo.setGoodsName(duolaGoods.getGoodsName());
        vo.setGoodsId(duolaGoods.getId());
        return vo;
    }

    /**
     * 装料取消
     *
     * @param transId
     */
    @Override
    public void loadGoodsCancel(Integer transId,Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"装料取消"+ JSON.toJSON(transId));
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(transId);
        if (duolaTransOrder == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //移除队列
        DuolaLineTrans duolaLineTrans = duolaLineTransMapper.selectByPrimaryKey(id);
        duolaLineTrans.setStatus(StatusEnums.YES.getEcode());
        duolaLineTransMapper.updateByPrimaryKeySelective(duolaLineTrans);
        duolaTransOrder.setStatus(StatusEnums.YES.getEcode());
        duolaTransOrder.setUpdateTime(LocalDateTime.now());
        transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
        //长连接
        socketService.sendNewTransLineSocket();
        //车辆变为空闲中
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(duolaTransOrder.getCarId());
        car.setTransStatus(CarTransStatusEnums.MIX_CAR.getEcode());
        car.setUpdateTime(LocalDateTime.now());
        duolaCarMapper.updateByPrimaryKeySelective(car);

    }

    /**
     * 装料排序
     *
     * @param loadGoodsSortDto
     */
    @Override
    public void loadGoodsSort(LoadGoodsSortDto loadGoodsSortDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"装料排序"+ JSON.toJSON(loadGoodsSortDto));
        Map<Integer,List<LoadGoodsSort>> DtoMap = new HashMap<>();
        //先找出原本的排序
        DuolaLineTransExample example = new DuolaLineTransExample();
        example.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode());
        example.setOrderByClause("sort asc");
        List<DuolaLineTrans> lineTrans = duolaLineTransMapper.selectByExample(example);
        //todo key id  value 老的队形
        Map<Integer, DuolaLineTrans> listMap = new HashMap<>();
        for (DuolaLineTrans lineTran : lineTrans) {
            listMap.put(lineTran.getId(),lineTran);
        }
//        //重新排序
//        Map<Integer,DuolaLineTransOldLast> oldLastMap = new HashMap<>();
//        for (Integer integer : listMap.keySet()) {
//            List<DuolaLineTransOldLast> duolaLineTransOldLasts = listMap.get(integer);
//            for (int i = 0; i < duolaLineTransOldLasts.size(); i++) {
//                DuolaLineTransOldLast last = duolaLineTransOldLasts.get(i);
//                last.setSort(i+1);
//                if (i!=0){
//                    last.setLastCarId(duolaLineTransOldLasts.get(i-1).getCarId());
//                }
//                oldLastMap.put(last.getId(),last);
//            }
//
//        }
        List<LoadGoodsSort> changeCarIds = new ArrayList<>();
        List<LoadGoodsSort> list = loadGoodsSortDto.getList();
        for (LoadGoodsSort loadGoodsSort : list) {
            if (DtoMap.get(loadGoodsSort.getLineId())==null){
                List<LoadGoodsSort> sortList = new ArrayList<>();
                sortList.add(loadGoodsSort);
                DtoMap.put(loadGoodsSort.getLineId(),sortList);
            }else {
                List<LoadGoodsSort> sortList = DtoMap.get(loadGoodsSort.getLineId());
                sortList.add(loadGoodsSort);
                DtoMap.put(loadGoodsSort.getLineId(),sortList);
            }
        }
        List<LoadGoodsSort> newList = new ArrayList<>();

        Iterator<Map.Entry<Integer, List<LoadGoodsSort>>> iterator = DtoMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<Integer, List<LoadGoodsSort>> next = iterator.next();
            for (int i = 0; i < next.getValue().size(); i++) {
                LoadGoodsSort loadGoodsSort = next.getValue().get(i);
                if (i!=0){
                    loadGoodsSort.setLastCarId(list.get(i-1).getCarId());
                }else {
                    loadGoodsSort.setLastCarId(0);
                }
                newList.add(loadGoodsSort);
            }
        }
//        DuolaLineTrans duolaLineTrans = duolaLineTransMapper.selectByPrimaryKey(loadGoodsSort.getId());
        //todo key id value 新的队形
        Map<Integer,LoadGoodsSort> newSort = new HashMap<>();
        for (LoadGoodsSort loadGoodsSort : newList) {
            newSort.put(loadGoodsSort.getId(),loadGoodsSort);
            DuolaLineTrans duolaLineTrans = new DuolaLineTrans();
            duolaLineTrans.setId(loadGoodsSort.getId());
            System.out.println(duolaLineTrans);
            duolaLineTrans.setLineId(loadGoodsSort.getLineId());
            duolaLineTrans.setSort(loadGoodsSort.getSort());
            duolaLineTrans.setLastCarId(loadGoodsSort.getLastCarId());
            System.out.println(duolaLineTrans);
            duolaLineTransMapper.updateByPrimaryKeySelective(duolaLineTrans);
        }
        System.out.println("123");
        //长连接
        socketService.sendNewTransLineSocket();
        findDiff(listMap,newSort);
    }


    @Async
    public void findDiff(Map<Integer, DuolaLineTrans> oldSort, Map<Integer, LoadGoodsSort> newSort){
        List<DuolaLineTrans> changeList = new ArrayList<>();
        for (Map.Entry<Integer, LoadGoodsSort> integerDuolaLineTransEntry : newSort.entrySet()) {
            LoadGoodsSort newsSort = integerDuolaLineTransEntry.getValue();
            DuolaLineTrans oldsSort = oldSort.get(integerDuolaLineTransEntry.getKey());
            if (!newsSort.getLastCarId().equals(oldsSort.getLastCarId())||!newsSort.getLineId().equals(oldsSort.getLineId())){
                DuolaLineTrans change = new DuolaLineTrans();
                change.setId(newsSort.getId());
                change.setLineId(newsSort.getLineId());
                change.setCarId(newsSort.getCarId());
                change.setLastCarId(newsSort.getLastCarId());
                change.setTransId(newsSort.getTransId());
                change.setSort(newsSort.getSort());
                change.setStatus(StatusEnums.NO.getEcode());
                changeList.add(change);
            }

        }
        //查询电话等联系方式
        List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(new DuolaCarExample());
        Map<Integer,DuolaCar> carMap = new HashMap<>();
        for (DuolaCar duolaCar : duolaCars) {
            carMap.put(duolaCar.getId(),duolaCar);
        }
        for (DuolaLineTrans duolaLineTrans : changeList) {
            //查询前一辆车
            Integer lastCar = null;
//                DuolaLineTrans duolaLineTrans2 = duolaLineTransMapper.selectByPrimaryKey(duolaLineTrans.getId());
                if (!duolaLineTrans.getLastCarId().equals(0)){
                    lastCar = duolaLineTrans.getLastCarId();
                }

            DuolaCar duolaCar = carMap.get(duolaLineTrans.getCarId());
            SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(duolaCar.getDriverId());
            String lastCarNo = "无";
            if (lastCar!=null){
                DuolaCar last = carMap.get(lastCar);
                lastCarNo = last.getCarNo();
            }
            if (sysUserWithBLOBs!=null){
//                System.out.println("修改了的车辆"+duolaCar.getCarNo()+"生产线"+duolaLineTrans2.getLineId()+"上一辆车"+lastCarNo);
                noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),duolaCar.getCarNo(),duolaLineTrans.getLineId().toString(),lastCarNo);
            }

        }
        //拨打电话


    }

    /**
     * 运输完成
     *
     * @param transFinishDto
     */
    @Override
    public void transFinish(TransFinishDto transFinishDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"运输完成"+ JSON.toJSON(transFinishDto));
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(transFinishDto.getTransId());
        if (duolaTransOrder == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
//        //如果车辆是在待装料的状态点运输完成
//        if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.WAIT_LOAD.getEcode())){
//            DuolaLineTrans duolaLineTrans = duolaLineTransMapper.selectByPrimaryKey(transFinishDto.getTransId());
//            duolaLineTrans.setStatus(StatusEnums.YES.getEcode());
//            duolaLineTransMapper.updateByPrimaryKeySelective(duolaLineTrans);
//        }
//        其他状态
        duolaTransOrder.setOrderStatus(TransOrderStatusEnums.FINISH.getEcode());
        duolaTransOrder.setFinishTime(LocalDateTime.now());
        duolaTransOrder.setSignVolume(transFinishDto.getSignVolume());
        duolaTransOrder.setRemark(transFinishDto.getRemark());
        duolaTransOrder.setUpdateTime(LocalDateTime.now());
        transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
        //更新车辆余料
        DuolaCarRemain duolaCarRemain = duolaCarRemainMapper.selectByPrimaryKey(duolaTransOrder.getCarId());
        duolaCarRemain.setRemain(transFinishDto.getRemainVolume());
        duolaCarRemain.setLastTransId(duolaTransOrder.getId());
//        duolaTransOrder.set(transFinishDto.getSignVolume());
        duolaCarRemainMapper.updateByPrimaryKeySelective(duolaCarRemain);
        //更新车辆状态
        DuolaCar car = new DuolaCar();
        car.setId(duolaTransOrder.getCarId());
        car.setTransStatus(CarTransStatusEnums.MIX_CAR.getEcode());
        duolaCarMapper.updateByPrimaryKeySelective(car);
        socketService.sendNewTransOrderListSocket();
    }

    /**
     * 退料转料
     *
     * @param returnTransferDto
     */
    @Override
    public void returnTransfer(ReturnTransferDto returnTransferDto) throws Exception {
        Boolean flag = Boolean.FALSE;
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"退料转料"+ JSON.toJSON(returnTransferDto));
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(returnTransferDto.getTransId());
        if (duolaTransOrder == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        duolaTransOrder.setSignVolume(returnTransferDto.getSignVolume());
        switch (returnTransferDto.getType()) {
            case 1:
                //盘盈转料
                duolaTransOrder.setSignVolume(returnTransferDto.getSignVolume());
                duolaTransOrder.setFinishTime(LocalDateTime.now());
                duolaTransOrder.setOrderStatus(TransOrderStatusEnums.FINISH.getEcode());
                duolaTransOrder.setUpdateTime(LocalDateTime.now());
                transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
                //创建新工地的运输单 数量为总量-剩料 todo 选择运输类型
                DuolaTransOrder transOrder = new DuolaTransOrder();
                transOrder.setStatus(StatusEnums.NO.getEcode());
                transOrder.setPlanId(returnTransferDto.getPlanId());
                transOrder.setProjectId(returnTransferDto.getProjectId());
                transOrder.setTotalVolume(duolaTransOrder.getTotalVolume() - returnTransferDto.getSignVolume());
                transOrder.setSendType(returnTransferDto.getSendType());
                transOrder.setLeaveMixTime(duolaTransOrder.getLeaveMixTime());
                //如果需要回搅拌站装料的
                if (returnTransferDto.getBackPlan()!=null&&returnTransferDto.getBackPlan()){
                    transOrder.setOrderStatus(TransOrderStatusEnums.WAIT_LOAD.getEcode());
                    transOrder.setLineId(returnTransferDto.getLineId());
                }else {
                    transOrder.setOrderStatus(TransOrderStatusEnums.TRANS_ING.getEcode());
                    transOrder.setFormulaId(duolaTransOrder.getFormulaId());
                    transOrder.setLineId(duolaTransOrder.getLineId());
                    transOrder.setStartTime(duolaTransOrder.getStartTime());
                    transOrder.setFormulaId(duolaTransOrder.getFormulaId());
                }
                transOrder.setAddTime(LocalDateTime.now());
                DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(duolaTransOrder.getProjectId());
                transOrder.setAddUid(userId);
                transOrder.setDistance(duolaProject.getDistance());
                transOrder.setCarId(duolaTransOrder.getCarId());
                transOrder.setGoodsId(duolaTransOrder.getGoodsId());
                transOrder.setCarNo(duolaTransOrder.getCarNo());
                transOrderMapper.insertSelective(transOrder);
                if (returnTransferDto.getBackPlan()!=null&&returnTransferDto.getBackPlan()){
                   this.sort(transOrder.getLineId(),transOrder.getCarId(),transOrder.getId());
                }
                break;
            case 2:
                //整车转料
                duolaTransOrder.setPlanId(returnTransferDto.getPlanId());
                duolaTransOrder.setProjectId(returnTransferDto.getProjectId());
                duolaTransOrder.setOrderStatus(TransOrderStatusEnums.TRANS_ING.getEcode());
                duolaTransOrder.setUpdateTime(LocalDateTime.now());
                transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
                break;
            case 3:
                //废料
                duolaTransOrder.setPlanId(returnTransferDto.getPlanId());
                duolaTransOrder.setOrderStatus(TransOrderStatusEnums.BACK.getEcode());
                duolaTransOrder.setWasteVolume(returnTransferDto.getWasteVolume());
                duolaTransOrder.setUpdateTime(LocalDateTime.now());
                transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
                break;
        }
        //更新车辆余料
        DuolaCarRemain duolaCarRemain = duolaCarRemainMapper.selectByPrimaryKey(duolaTransOrder.getCarId());
        Double signVolume = returnTransferDto.getSignVolume()==null?new Double(0): returnTransferDto.getSignVolume();
        Double totalVolume = duolaTransOrder.getTotalVolume();
        duolaCarRemain.setRemain(totalVolume-signVolume);
        duolaCarRemainMapper.updateByPrimaryKeySelective(duolaCarRemain);
        socketService.sendNewTransOrderListSocket();
        if (flag){
            socketService.sendNewTransLineSocket();
        }

    }


    /**
     * 排序车辆
     */
    @Async
    public void sort(Integer lineId,Integer carsId,Integer transId){
        //生产线进行排队
        Integer sort = 1;
        DuolaLineTransExample example = new DuolaLineTransExample();
        example.createCriteria().andLineIdEqualTo(lineId).andStatusEqualTo(StatusEnums.NO.getEcode());
        example.setOrderByClause("sort desc");
        List<DuolaLineTrans> duolaLineTrans = duolaLineTransMapper.selectByExample(example);
        if (duolaLineTrans.size() > 0) {
            sort = duolaLineTrans.get(0).getSort() + 1;
        }
        DuolaLineTrans newTrans = new DuolaLineTrans();
        newTrans.setCarId(carsId);
        newTrans.setStatus(StatusEnums.NO.getEcode());
        newTrans.setTransId(transId);
        newTrans.setSort(sort);
        DuolaLineTransExample lastExample = new DuolaLineTransExample();
        lastExample.createCriteria().andLineIdEqualTo(lineId).andStatusEqualTo(StatusEnums.NO.getEcode()).andSortEqualTo(sort-1);
        List<DuolaLineTrans> lastCarList = duolaLineTransMapper.selectByExample(lastExample);
        if (lastCarList!=null&&lastCarList.size()>0){
            newTrans.setLastCarId(lastCarList.get(0).getCarId());
        }else {
            newTrans.setLastCarId(0);
        }
        newTrans.setLineId(lineId);
        duolaLineTransMapper.insertSelective(newTrans);
        //查询前一辆车
        DuolaCar lastCar = null;
        if (duolaLineTrans.size()>0){
            DuolaLineTrans lastTrans = duolaLineTrans.get(0);
            if (lastTrans!=null){
                Integer carId = lastTrans.getCarId();
                lastCar = duolaCarMapper.selectByPrimaryKey(carId);

            }
        }
        //发送生产线长连接
        socketService.sendNewTransLineSocket();
        //车变为运输中的状态
        DuolaCar duolaCar = duolaCarMapper.selectByPrimaryKey(carsId);
        duolaCar.setTransStatus(CarTransStatusEnums.BUMP_CAR.getEcode());
        duolaCarMapper.updateByPrimaryKeySelective(duolaCar);
        //查询司机
        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(duolaCar.getDriverId());
        socketService.sendNewTransOrderListSocket();
        //todo 装料通知
        if (lastCar!=null){
            noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),duolaCar.getCarNo(),lineId.toString(),lastCar.getCarNo());
        }else {
            noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),duolaCar.getCarNo(),lineId.toString(),"空");
        }
    }

    /**
     * 运输方量统计
     *
     * @param transVolumeCountDto
     * @return
     */
    @Override
    public TransVolumeCount transVolumeCount(TransVolumeCountDto transVolumeCountDto) {
        TransVolumeCount volumeCount = new TransVolumeCount();
        List<TransVolumeCountVo>list=new ArrayList<>();

        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"运输方量统计"+ JSON.toJSON(transVolumeCountDto));
        DuolaTransOrderExample transOrderExample = new DuolaTransOrderExample();
        DuolaTransOrderExample.Criteria criteria = transOrderExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode())
                .andOrderStatusEqualTo(TransOrderStatusEnums.FINISH.getEcode())
//                .andFinishTimeBetween(TimeTool.LongToLocalDateTime(transVolumeCountDto.getTime()));
                .andFinishTimeBetween(TimeTool.getDayBeginLocalDateTime(TimeTool.LongToLocalDate(transVolumeCountDto.getStartTime())), TimeTool.getDayEndLocalDateTime(TimeTool.LongToLocalDate(transVolumeCountDto.getEndTime())));
        if (!StringUtils.isEmpty(transVolumeCountDto.getCarNo())){
            criteria.andCarNoLike(transVolumeCountDto.getCarNo());
        }
        Map<Integer,TransVolumeCountVo> voMap = new HashMap<>();

        //获取所有工地距离
        Map<Integer,Integer> distanceMap = new HashMap<>();
        List<DuolaProject> duolaProjects = duolaProjectMapper.selectByExample(new DuolaProjectExample());
        for (DuolaProject duolaProject : duolaProjects) {
            distanceMap.put(duolaProject.getId(),(int)Math.round(duolaProject.getDistance()));
        }
        //获取所有人员名称
        Map<Long,String> driverName = new HashMap<>();
        List<SysUser> sysUsers = sysUserMapper.selectByExample(new SysUserExample());
        for (SysUser sysUser : sysUsers) {
            driverName.put(sysUser.getId(),sysUser.getNickname());
        }
        //获取所有车辆
        Map<Integer,Long> carMap = new HashMap<>();
        List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(new DuolaCarExample());
        for (DuolaCar duolaCar : duolaCars) {
            if (duolaCar.getDriverId()!=null){
                carMap.put(duolaCar.getId(),duolaCar.getDriverId());
            }
        }
        //获取所有计划
        List<DuolaTransOrder> transOrders = transOrderMapper.selectByExample(transOrderExample);
        Map<Integer,Object> otherDistanceMap = new HashMap<>();
        List<Integer> otherDistanceList = new ArrayList<>();
        Map<Integer,Double> ten = new HashMap<>();
        Map<Integer,Double> eleven = new HashMap<>();
        Map<Integer,Double> fifteen = new HashMap<>();
        Map<Integer,Double> twentySix = new HashMap<>();
        Map<Integer,Map<Integer, TransOtherVo>> otherMap = new HashMap<>();
        Map<Integer, TransOtherVo> TransOtherVoMap = new HashMap<>();
        for (DuolaTransOrder duolaTransOrder : transOrders) {
            if (duolaTransOrder.getProjectId()!=null&&duolaTransOrder.getSignVolume()!=null){
                TransVolumeCountVo countVo = new TransVolumeCountVo();
                countVo.setCarNo(duolaTransOrder.getCarNo());
                //获取车辆
                Long driverId = carMap.get(duolaTransOrder.getCarId());
                if(driverId!=null){
                    countVo.setDriverName(driverName.get(driverId));
                }
                countVo.setDate(TimeTool.LocalDateTimeFormatNoTime(duolaTransOrder.getFinishTime()));
                voMap.put(duolaTransOrder.getCarId(),countVo);
                Integer distance = distanceMap.get(duolaTransOrder.getProjectId());
                //十公里以内
                if (distance<=10){
                    if (ten.get(duolaTransOrder.getCarId())==null){
                        ten.put(duolaTransOrder.getCarId(),duolaTransOrder.getSignVolume());
                    }else {
                        ten.put(duolaTransOrder.getCarId(),ten.get(duolaTransOrder.getCarId())+duolaTransOrder.getSignVolume());
                    }
                }else
                //11-15公里
                if (distance<=15&&distance>10){
                    if (eleven.get(duolaTransOrder.getCarId())==null){
                        eleven.put(duolaTransOrder.getCarId(),duolaTransOrder.getSignVolume());
                    }else {
                        eleven.put(duolaTransOrder.getCarId(),eleven.get(duolaTransOrder.getCarId())+duolaTransOrder.getSignVolume());
                    }
                }else
                //16-25公里
                if (distance<=25&&distance>16){
                    if (fifteen.get(duolaTransOrder.getCarId())==null){
                        fifteen.put(duolaTransOrder.getCarId(),duolaTransOrder.getSignVolume());
                    }else {
                        fifteen.put(duolaTransOrder.getCarId(),fifteen.get(duolaTransOrder.getCarId())+duolaTransOrder.getSignVolume());
                    }
                }else
                //26-32公里
                if (distance<=32&&distance>26){
                    if (twentySix.get(duolaTransOrder.getCarId())==null){
                        twentySix.put(duolaTransOrder.getCarId(),duolaTransOrder.getSignVolume());
                    }else {
                        twentySix.put(duolaTransOrder.getCarId(),twentySix.get(duolaTransOrder.getCarId())+duolaTransOrder.getSignVolume());
                    }
                    //超过32公里的
                }else {
                    if (otherMap.get(duolaTransOrder.getCarId())==null){
                        TransOtherVo vo = new TransOtherVo();
                        vo.setDistance(distance);
                        vo.setCounts(duolaTransOrder.getSignVolume());
                        TransOtherVoMap.put(duolaTransOrder.getCarId(),vo);
                        otherMap.put(duolaTransOrder.getCarId(),TransOtherVoMap);
                    }else {
                        TransOtherVo vo = TransOtherVoMap.get(duolaTransOrder.getCarId());
                        vo.setCounts(vo.getCounts()+duolaTransOrder.getSignVolume());
                        TransOtherVoMap.put(duolaTransOrder.getCarId(),vo);
                        otherMap.put(duolaTransOrder.getCarId(),TransOtherVoMap);
                    }
                    otherDistanceMap.put((int)Math.round(duolaTransOrder.getDistance()),null);
                }

            }
        }
        //十公里以内
        for (Map.Entry<Integer, TransVolumeCountVo> integerTransVolumeCountVoEntry : voMap.entrySet()) {
            TransVolumeCountVo value = integerTransVolumeCountVoEntry.getValue();
            value.setTen(ten.get(integerTransVolumeCountVoEntry.getKey())==null?new Double(0):ten.get(integerTransVolumeCountVoEntry.getKey()));
            value.setEleven(eleven.get(integerTransVolumeCountVoEntry.getKey())==null?new Double(0):eleven.get(integerTransVolumeCountVoEntry.getKey()));
            value.setFifteen(fifteen.get(integerTransVolumeCountVoEntry.getKey())==null?new Double(0):fifteen.get(integerTransVolumeCountVoEntry.getKey()));
            value.setTwentySix(twentySix.get(integerTransVolumeCountVoEntry.getKey())==null?new Double(0):twentySix.get(integerTransVolumeCountVoEntry.getKey()));
            List<TransOtherVo> other = new ArrayList<>();
            if (otherMap.get(integerTransVolumeCountVoEntry.getKey())!=null){
                for (Map.Entry<Integer, TransOtherVo> integerTransOtherVoEntry : otherMap.get(integerTransVolumeCountVoEntry.getKey()).entrySet()) {
                    other.add(integerTransOtherVoEntry.getValue());
                }
                value.setOther(other);
            }
            voMap.put(integerTransVolumeCountVoEntry.getKey(),value);
        }
        list=new ArrayList<TransVolumeCountVo>(voMap.values());
        otherDistanceList=new ArrayList<Integer>(otherDistanceMap.keySet());
        Collections.sort(otherDistanceList);
        volumeCount.setList(list);
        volumeCount.setOtherDistanceList(otherDistanceList);
        return volumeCount;
    }

    /**
     * 根据经纬度判断是否需要改变运输单状态
     *
     * @param vo
     */
    @Override
    @Async
    public void transStatus(CarLocationVo vo) {
        Boolean flag = false;
        logger.debug("根据经纬度判断是否需要改变运输单状态"+ JSON.toJSON(vo));
        DuolaTransOrderExample example = new DuolaTransOrderExample();
        example.createCriteria().andCarIdEqualTo(vo.getId()).andOrderStatusNotEqualTo(TransOrderStatusEnums.FINISH.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaTransOrder> transOrders = transOrderMapper.selectByExample(example);
        if (transOrders.size()>0){
            DuolaTransOrder duolaTransOrder = transOrders.get(0);
            //判断车辆在搅拌站和工地的距离
            Integer projectId = duolaTransOrder.getProjectId();
            DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(projectId);
            //获取工地的经纬度
            Double projectLatitude = duolaProject.getLatitude();
            Double projectLongitude = duolaProject.getLongitude();
            //105.990551,34.543941
            Double project_distance = DistanceUtil.getDistance(vo.getLatitude(), vo.getLongitude(), projectLatitude, projectLongitude);
            Double plan_distance = DistanceUtil.getDistance(vo.getLatitude(), vo.getLongitude(), 34.543941, 105.990551);
            //待装料
            if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.WAIT_LOAD.getEcode())){
                //如果不在在搅拌站500米内 就加入异常并报警
                if (plan_distance>=500){
//                    System.out.println("报警了");
                }
            }
            //装料完成
            if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.LOAD_FINISH.getEcode())){
                //如果超过搅拌站500米外就改为运输中
                if (plan_distance>=500){
                    duolaTransOrder.setOrderStatus(TransOrderStatusEnums.TRANS_ING.getEcode());
                    duolaTransOrder.setLeaveMixTime(LocalDateTime.now());
                    duolaTransOrder.setUpdateTime(LocalDateTime.now());
                    flag = true;
                }
            }
            //运输中
            if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.TRANS_ING.getEcode())){
                //如果到达工地300米内就改为到达工地
                if (project_distance<=300){
                    duolaTransOrder.setOrderStatus(TransOrderStatusEnums.ARRIVAL_SITE.getEcode());
                    duolaTransOrder.setArrivalSiteTime(LocalDateTime.now());
                    duolaTransOrder.setUpdateTime(LocalDateTime.now());
                    flag = true;
                }
            }
            //到达工地
            if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.ARRIVAL_SITE.getEcode())){
                //如果离开工地500米外就改为回程中
                if (project_distance>=500){
                    duolaTransOrder.setOrderStatus(TransOrderStatusEnums.BACK.getEcode());
                    duolaTransOrder.setLeaveSiteTime(LocalDateTime.now());
                    duolaTransOrder.setUpdateTime(LocalDateTime.now());
                    flag = true;
                }
            }
            //回程中或者退料回程中
            if (duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.BACK.getEcode())||duolaTransOrder.getOrderStatus().equals(TransOrderStatusEnums.RETURN_BACK.getEcode())){
                //如果到达搅拌站500米内 改为待过磅
                if (plan_distance<=500){
                    duolaTransOrder.setOrderStatus(TransOrderStatusEnums.WAIT_WEIGH.getEcode());
                    duolaTransOrder.setReturnMixTime(LocalDateTime.now());
                    duolaTransOrder.setUpdateTime(LocalDateTime.now());
                    flag = true;
                }
            }
            if (  flag ){
                int i = transOrderMapper.updateByPrimaryKeySelective(duolaTransOrder);
                //发送长连接
                socketService.sendNewTransOrderListSocket();
            }

        }

    }

    @Override
    public Double history(Integer carId) {
        Double total = new Double(0);
        DuolaTransOrderExample duolaTransOrderExample = new DuolaTransOrderExample();
        duolaTransOrderExample.createCriteria().andCarIdEqualTo(carId).andStatusEqualTo(StatusEnums.NO.getEcode()).andOrderStatusEqualTo(TransOrderStatusEnums.FINISH.getEcode());
        List<DuolaTransOrder> transOrders = transOrderMapper.selectByExample(duolaTransOrderExample);
        for (DuolaTransOrder transOrder : transOrders) {
            total = total+transOrder.getTotalVolume();
        }
        return  total;
    }

    /**
     * 根据长短距离和发货类型自主选择车辆
     *
     * @param planId
     * @param sendType
     * @return
     */
    @Override
    public RecommendCarVo recommendCar(Integer planId, Integer sendType,Double volume) {

        DuolaCarExample carExample = new DuolaCarExample();
        carExample.createCriteria().andCarTypeEqualTo(CarTypeEnums.MIX_CAR.getEcode()).andCapacityGreaterThanOrEqualTo(volume).andTransStatusEqualTo(CarTransStatusEnums.MIX_CAR.getEcode());
        List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(carExample);
        List<Integer> carIds = new ArrayList<>();
        Map<Integer,Integer> countMap  = new HashMap<>();
        Map<Integer,String> carNoMap  = new HashMap<>();
        for (DuolaCar duolaCar : duolaCars) {
            carIds.add(duolaCar.getId());
            countMap.put(duolaCar.getId(),0);
            carNoMap.put(duolaCar.getId(),duolaCar.getCarNo());
        }
        if (duolaCars.size()>0){
            //根据现有的类型和距离 查询次数最少的车辆
            DuolaPlan duolaPlan = duolaPlanMapper.selectByPrimaryKey(planId);
            Integer projectId = duolaPlan.getProjectId();
            DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(projectId);
            Double distance = duolaProject.getDistance();
            DuolaTransOrderExample transOrderExample = new DuolaTransOrderExample();
            LocalDateTime date = LocalDateTime.now();
            LocalDateTime firstday = date.with(TemporalAdjusters.firstDayOfMonth());
            LocalDateTime lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
            DuolaTransOrderExample.Criteria criteria = transOrderExample.createCriteria().andOrderStatusEqualTo(OrderStatusEnums.FINISH.getEcode()).andAddTimeBetween(firstday, lastDay).andStatusEqualTo(StatusEnums.NO.getEcode()).andCarIdIn(carIds).andSendTypeEqualTo(sendType);
            //长距离
            if (distance>=15000.00){
                criteria.andDistanceGreaterThanOrEqualTo(15000.00);
            }else {
                criteria.andDistanceLessThanOrEqualTo(15000.00);
            }
            List<SelectNumByGroup> transOrders = transOrderMapper.selectNumByGroup(transOrderExample);
            for (SelectNumByGroup transOrder : transOrders) {
                countMap.put(transOrder.getCarId(),transOrder.getNum());
            }

            List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer, Integer>>(countMap.entrySet()); //转换为list
            list.sort(new Comparator<Map.Entry<Integer, Integer>>() {
                @Override
                public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                    return o2.getValue().compareTo(o1.getValue());
                }
            });
            RecommendCarVo vo = new RecommendCarVo();
            vo.setId(list.get(0).getKey());
            vo.setCarNo(carNoMap.get(vo.getId()));
            return vo;

        }
        return null;
    }

    /**
     * 获取所有空闲可用的车辆 传入方量,车牌号  不传显示所有
     *
     * @param carNo
     * @param volume
     * @return
     */
    @Override
    public List<GetAllFreeCarListVo> getAllFreeCarList(String carNo, Double volume) {
        List<GetAllFreeCarListVo> listVos = new ArrayList<>();
        DuolaCarExample carExample = new DuolaCarExample();
        DuolaCarExample.Criteria criteria = carExample.createCriteria();
        if (!StringUtils.isEmpty(carNo)){
            criteria.andCarNoLike(carNo);
        }
        if (volume!=null){
            criteria.andCapacityLessThanOrEqualTo(volume);
        }
        criteria.andCarStatusEqualTo(CarTransStatusEnums.MIX_CAR.getEcode());
        List<DuolaCar> duolaCars = duolaCarMapper.selectByExample(carExample);
        for (DuolaCar duolaCar : duolaCars) {
            GetAllFreeCarListVo vc = new GetAllFreeCarListVo();
            vc.setCarId(duolaCar.getId());
            vc.setCarNo(duolaCar.getCarNo());
            listVos.add(vc);
        }
        return listVos;
    }

    /**
     * 通过合同id 获取已发货数量
     *
     * @param id
     * @return
     */
    @Override
    public Double getSendVolumeByProjectId(Integer id) {
        Double total = new Double(0);
        DuolaTransOrderExample example = new DuolaTransOrderExample();
        example.createCriteria().andProjectIdEqualTo(id).andOrderStatusGreaterThanOrEqualTo(TransOrderStatusEnums.TRANS_ING.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaTransOrder> transOrders = transOrderMapper.selectByExample(example);
        for (DuolaTransOrder transOrder : transOrders) {
            if (transOrder.getSignVolume()!=null){
                total=total+transOrder.getSignVolume();
            }
        }
        return total;
    }

    /**
     * 退料转料跳转
     *
     * @param transId
     * @return
     */
    @Override
    public ReturnTransferJumpVo returnTransferJump(Integer transId) throws Exception {
        DuolaTransOrder duolaTransOrder = transOrderMapper.selectByPrimaryKey(transId);
        if (duolaTransOrder==null){
            throw  new Exception( ErrorEnums.ERROR_DATA.getEmsg());
        }
        //获取生产计划中的内容
        DuolaPlan duolaPlan = duolaPlanMapper.selectByPrimaryKey(duolaTransOrder.getPlanId());
        ReturnTransferJumpVo vo = new ReturnTransferJumpVo();
        vo.setPlanId(duolaPlan.getId());
        vo.setCustomerId(duolaPlan.getCustomerId());
        DuolaCustomer duolaCustomer = duolaCustomerMapper.selectByPrimaryKey(duolaPlan.getCustomerId());
        if (duolaCustomer!=null){
            vo.setCustomerName(duolaCustomer.getCustomerName());
        }
        vo.setProjectName(duolaPlan.getProjectName());
        vo.setProjectId(duolaPlan.getProjectId());
        vo.setGoodsId(duolaTransOrder.getGoodsId());
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(duolaTransOrder.getCarId());
        vo.setCarModel(car.getCapacity());
        vo.setCarNo(car.getCarNo());
        vo.setSendType(duolaTransOrder.getSendType());
        vo.setAddress(duolaPlan.getProjectAddress());
        DuolaGoods duolaGoods = duolaGoodsMapper.selectByPrimaryKey(duolaTransOrder.getGoodsId());
        if (duolaGoods!=null){
            vo.setGoodsName(duolaGoods.getGoodsName());
        }
        vo.setSendNum(duolaTransOrder.getTotalVolume());

        return vo;
    }

    /**
     * 通过车辆id获取最新运输单
     *
     * @param carId
     * @param lat
     * @param lng
     * @return
     */
    @Override
    public GetLastTransOrderByCarIdVo getLastTransOrderByCarId(Integer carId, Double lat, Double lng) throws Exception {
        //todo
        DuolaTransOrderExample duolaTransOrderExample = new DuolaTransOrderExample();
        duolaTransOrderExample.createCriteria().andCarIdEqualTo(carId).andOrderStatusEqualTo(TransOrderStatusEnums.ARRIVAL_SITE.getEcode());
        List<DuolaTransOrder> duolaTransOrders = transOrderMapper.selectByExample(duolaTransOrderExample);
        if (duolaTransOrders.size()<=0){
            throw new Exception(ErrorEnums.HAVE_NO_TRANSORDER.getEmsg());
        }
        DuolaTransOrder duolaTransOrder = duolaTransOrders.get(0);
        //查询工程
        DuolaProject duolaProject = duolaProjectMapper.selectByPrimaryKey(duolaTransOrder.getProjectId());
        if (duolaProject==null){
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //如果大于500米就无法进行签收
        Double plan_distance = DistanceUtil.getDistance(lat, lng, duolaProject.getLatitude(), duolaProject.getLongitude());
        if (plan_distance>500){
            throw new Exception(ErrorEnums.TOO_FAR_FROM_PROJECT.getEmsg());
        }
        //查询车辆
        DuolaCar duolaCar = duolaCarMapper.selectByPrimaryKey(carId);
        //查询司机
        SysUserWithBLOBs sysUserWithBLOBs = userMapper.selectByPrimaryKey(duolaCar.getDriverId());
        //查询计划
        DuolaPlan duolaPlan = duolaPlanMapper.selectByPrimaryKey(duolaTransOrder.getPlanId());
        //查询物料
        DuolaGoods duolaGoods = duolaGoodsMapper.selectByPrimaryKey(duolaTransOrder.getGoodsId());
        GetLastTransOrderByCarIdVo vo = new GetLastTransOrderByCarIdVo();
        vo.setCarNo(duolaCar.getCarNo());
        vo.setGoodsName(duolaGoods.getGoodsName());
        vo.setPartName(duolaPlan.getPart());
        vo.setTotalVolume(duolaTransOrder.getTotalVolume());
        vo.setTransId(duolaTransOrder.getId());
        vo.setDriverId(duolaCar.getDriverId());
        vo.setDriverName(sysUserWithBLOBs.getNickname());
        return vo;
    }

    /**
     * 通知车辆前来装料
     *
     * @param noticeCarDto
     */
    @Override
    public void noticeCar(NoticeCarDto noticeCarDto) {
        Integer transId = noticeCarDto.getTransId();
        DuolaLineTrans duolaLineTrans1 = duolaLineTransMapper.selectByPrimaryKey(transId);
        //生产线进行排队
        //查询前一辆车
        Integer lastCarId = null;
        DuolaLineTransExample example = new DuolaLineTransExample();
        example.createCriteria().andLineIdEqualTo(duolaLineTrans1.getLineId()).andStatusEqualTo(StatusEnums.NO.getEcode()).andSortLessThan(duolaLineTrans1.getSort());
        example.setOrderByClause("sort desc");
        List<DuolaLineTrans> duolaLineTrans = duolaLineTransMapper.selectByExample(example);
        if (duolaLineTrans.size() > 0) {
            lastCarId = duolaLineTrans.get(0).getCarId();
        }
//        DuolaLineTrans newTrans = new DuolaLineTrans();
//        newTrans.setCarId(duolaLineTrans1.getCarId());
//        newTrans.setStatus(StatusEnums.NO.getEcode());
//        newTrans.setTransId(duolaLineTrans1.getId());
//        newTrans.setSort(sort);
//        DuolaLineTransExample lastExample = new DuolaLineTransExample();
//        lastExample.createCriteria().andLineIdEqualTo(duolaLineTrans1.getLineId()).andStatusEqualTo(StatusEnums.NO.getEcode()).andSortEqualTo(sort-1);
//        List<DuolaLineTrans> lastCarList = duolaLineTransMapper.selectByExample(lastExample);
//        if (lastCarList!=null&&lastCarList.size()>0){
//            newTrans.setLastCarId(lastCarList.get(0).getCarId());
//        }else {
//            newTrans.setLastCarId(0);
//        }
//        newTrans.setLineId(duolaLineTrans1.getLineId());
//        duolaLineTransMapper.insertSelective(newTrans);
        DuolaCar lastCar = null;
        if (duolaLineTrans.size()>0){
            DuolaLineTrans lastTrans = duolaLineTrans.get(0);
            if (lastTrans!=null){
                lastCar = duolaCarMapper.selectByPrimaryKey(lastCarId);
            }
        }
        DuolaCar car = duolaCarMapper.selectByPrimaryKey(duolaLineTrans1.getCarId());

        SysUserWithBLOBs sysUserWithBLOBs = sysUserMapper.selectByPrimaryKey(car.getDriverId());
        //todo 装料通知
        if (lastCar!=null){
            noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),car.getCarNo(),duolaLineTrans1.getLineId().toString(),lastCar.getCarNo());
        }else {
            noticeService.loadGoods(sysUserWithBLOBs.getMobilePhone(),car.getCarNo(),duolaLineTrans1.getLineId().toString(),"空");
        }
    }


//    public static void main(String[] args) {
//        Double plan_distance = DistanceUtil.getDistance(34.555487, 105.862065, 34.543941, 105.990551);
//
//        System.out.println(plan_distance);
//    }
}
